summaryrefslogtreecommitdiffstats
path: root/mojo/common
diff options
context:
space:
mode:
authoryzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-05 18:40:13 +0000
committeryzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-05 18:40:13 +0000
commitc6426566282ddde4f41602316f0873459caa7175 (patch)
treefc0cb72561cf72ffc54ac7a839026064c1e33e84 /mojo/common
parent807460307c2ece425c46cd150d7db2a89d38cfe0 (diff)
downloadchromium_src-c6426566282ddde4f41602316f0873459caa7175.zip
chromium_src-c6426566282ddde4f41602316f0873459caa7175.tar.gz
chromium_src-c6426566282ddde4f41602316f0873459caa7175.tar.bz2
Implement PlatformChannelPair on Windows.
BUG=None TEST=multiprocess_test_base_unittest works on both Windows and POSIX. R=viettrungluu@chromium.org Review URL: https://codereview.chromium.org/148773004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@249059 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo/common')
-rw-r--r--mojo/common/test/multiprocess_test_base.cc33
-rw-r--r--mojo/common/test/multiprocess_test_base_unittest.cc132
2 files changed, 113 insertions, 52 deletions
diff --git a/mojo/common/test/multiprocess_test_base.cc b/mojo/common/test/multiprocess_test_base.cc
index 7785b93..028990e 100644
--- a/mojo/common/test/multiprocess_test_base.cc
+++ b/mojo/common/test/multiprocess_test_base.cc
@@ -8,7 +8,6 @@
#include "base/logging.h"
#include "base/process/kill.h"
#include "base/process/process_handle.h"
-// TODO(vtl): Remove build_config.h include when fully implemented on Windows.
#include "build/build_config.h"
#include "mojo/system/embedder/platform_channel_pair.h"
@@ -28,11 +27,8 @@ void MultiprocessTestBase::SetUp() {
MultiProcessTest::SetUp();
-// TODO(vtl): Not implemented on Windows yet.
-#if defined(OS_POSIX)
platform_channel_pair_.reset(new embedder::PlatformChannelPair());
server_platform_handle = platform_channel_pair_->PassServerHandle();
-#endif
}
void MultiprocessTestBase::TearDown() {
@@ -51,21 +47,23 @@ void MultiprocessTestBase::StartChild(const std::string& test_child_name) {
std::string test_child_main = test_child_name + "TestChildMain";
-#if defined(OS_POSIX)
CommandLine unused(CommandLine::NO_PROGRAM);
- base::FileHandleMappingVector fds_to_map;
- platform_channel_pair_->PrepareToPassClientHandleToChildProcess(&unused,
- &fds_to_map);
- test_child_handle_ = SpawnChild(test_child_main, fds_to_map, false);
+ embedder::HandlePassingInformation handle_passing_info;
+ platform_channel_pair_->PrepareToPassClientHandleToChildProcess(
+ &unused, &handle_passing_info);
+
+ base::LaunchOptions options;
+#if defined(OS_POSIX)
+ options.fds_to_remap = &handle_passing_info;
#elif defined(OS_WIN)
- test_child_handle_ = SpawnChild(test_child_main, false);
+ options.start_hidden = true;
+ options.handles_to_inherit = &handle_passing_info;
#else
#error "Not supported yet."
#endif
-// TODO(vtl): Not implemented on Windows yet.
-#if defined(OS_POSIX)
+
+ test_child_handle_ = SpawnChildWithOptions(test_child_main, options, false);
platform_channel_pair_->ChildProcessLaunched();
-#endif
CHECK_NE(test_child_handle_, base::kNullProcessHandle);
}
@@ -88,24 +86,19 @@ CommandLine MultiprocessTestBase::MakeCmdLine(const std::string& procname,
CommandLine command_line =
base::MultiProcessTest::MakeCmdLine(procname, debug_on_start);
-// TODO(vtl): Not implemented on Windows yet.
-#if defined(OS_POSIX)
- base::FileHandleMappingVector unused;
+ embedder::HandlePassingInformation unused;
platform_channel_pair_->PrepareToPassClientHandleToChildProcess(&command_line,
&unused);
-#endif
+
return command_line;
}
// static
void MultiprocessTestBase::ChildSetup() {
CHECK(CommandLine::InitializedForCurrentProcess());
-// TODO(vtl): Not implemented on Windows yet.
-#if defined(OS_POSIX)
client_platform_handle =
embedder::PlatformChannelPair::PassClientHandleFromParentProcess(
*CommandLine::ForCurrentProcess());
-#endif
}
// static
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