Index: mojo/system/multiprocess_message_pipe_unittest.cc |
diff --git a/mojo/system/multiprocess_message_pipe_unittest.cc b/mojo/system/multiprocess_message_pipe_unittest.cc |
index 458fe77d1479c99b581292548d739b2568022fdf..39a568355ec7cada0fef6738ec9684fb5e790a2a 100644 |
--- a/mojo/system/multiprocess_message_pipe_unittest.cc |
+++ b/mojo/system/multiprocess_message_pipe_unittest.cc |
@@ -3,19 +3,28 @@ |
// found in the LICENSE file. |
#include <stdint.h> |
+#include <stdio.h> |
#include <string> |
+#include <vector> |
-#include "base/basictypes.h" |
#include "base/bind.h" |
+#include "base/file_util.h" |
+#include "base/files/file_path.h" |
+#include "base/files/scoped_file.h" |
#include "base/location.h" |
#include "base/logging.h" |
+#include "base/macros.h" |
#include "base/threading/platform_thread.h" // For |Sleep()|. |
+#include "build/build_config.h" // TODO(vtl): Remove this. |
#include "mojo/common/test/multiprocess_test_helper.h" |
+#include "mojo/common/test/test_utils.h" |
#include "mojo/embedder/scoped_platform_handle.h" |
#include "mojo/system/channel.h" |
+#include "mojo/system/dispatcher.h" |
#include "mojo/system/local_message_pipe_endpoint.h" |
#include "mojo/system/message_pipe.h" |
+#include "mojo/system/platform_handle_dispatcher.h" |
#include "mojo/system/proxy_message_pipe_endpoint.h" |
#include "mojo/system/raw_channel.h" |
#include "mojo/system/test_utils.h" |
@@ -177,7 +186,6 @@ MOJO_MULTIPROCESS_TEST_CHILD_MAIN(EchoEcho) { |
MOJO_RESULT_OK); |
} |
- |
mp->Close(0); |
return rv; |
} |
@@ -272,6 +280,111 @@ TEST_F(MultiprocessMessagePipeTest, QueueMessages) { |
helper()->WaitForChildShutdown()); |
} |
+MOJO_MULTIPROCESS_TEST_CHILD_MAIN(CheckPlatformHandleFile) { |
+ ChannelThread channel_thread; |
+ embedder::ScopedPlatformHandle client_platform_handle = |
+ mojo::test::MultiprocessTestHelper::client_platform_handle.Pass(); |
+ CHECK(client_platform_handle.is_valid()); |
+ scoped_refptr<MessagePipe> mp(new MessagePipe( |
+ scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), |
+ scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); |
+ channel_thread.Start(client_platform_handle.Pass(), mp); |
+ |
+ CHECK_EQ(WaitIfNecessary(mp, MOJO_WAIT_FLAG_READABLE), MOJO_RESULT_OK); |
+ |
+ std::string read_buffer(100, '\0'); |
+ uint32_t num_bytes = static_cast<uint32_t>(read_buffer.size()); |
+ DispatcherVector dispatchers; |
+ uint32_t num_dispatchers = 10; // Maximum number to receive. |
+ CHECK_EQ(mp->ReadMessage(0, |
+ &read_buffer[0], &num_bytes, |
+ &dispatchers, &num_dispatchers, |
+ MOJO_READ_MESSAGE_FLAG_NONE), |
+ MOJO_RESULT_OK); |
+ mp->Close(0); |
+ |
+ read_buffer.resize(num_bytes); |
+ CHECK_EQ(read_buffer, std::string("hello")); |
+ CHECK_EQ(num_dispatchers, 1u); |
+ |
+ CHECK_EQ(dispatchers[0]->GetType(), Dispatcher::kTypePlatformHandle); |
+ |
+ scoped_refptr<PlatformHandleDispatcher> dispatcher( |
+ static_cast<PlatformHandleDispatcher*>(dispatchers[0].get())); |
+ embedder::ScopedPlatformHandle h = dispatcher->PassPlatformHandle().Pass(); |
+ CHECK(h.is_valid()); |
+ dispatcher->Close(); |
+ |
+ base::ScopedFILE fp(mojo::test::FILEFromPlatformHandle(h.Pass(), "r")); |
+ CHECK(fp); |
+ std::string fread_buffer(100, '\0'); |
+ size_t bytes_read = fread(&fread_buffer[0], 1, fread_buffer.size(), fp.get()); |
+ fread_buffer.resize(bytes_read); |
+ CHECK_EQ(fread_buffer, "world"); |
+ |
+ return 0; |
+} |
+ |
+#if defined(OS_POSIX) |
+#if defined(OS_MACOSX) |
+// TODO(vtl): Apparently, cmsgs on SOCK_STREAM AF_UNIX sockets don't work the |
+// way I thought they work, at least on Mac. (The non-control data gets merged |
+// with subsequent data.) |
+#define MAYBE_PlatformHandlePassing DISABLED_PlatformHandlePassing |
+#else |
+#define MAYBE_PlatformHandlePassing PlatformHandlePassing |
+#endif |
+#else |
+// Not yet implemented (on Windows). |
+#define MAYBE_PlatformHandlePassing DISABLED_PlatformHandlePassing |
+#endif |
+TEST_F(MultiprocessMessagePipeTest, MAYBE_PlatformHandlePassing) { |
+ helper()->StartChild("CheckPlatformHandleFile"); |
+ |
+ scoped_refptr<MessagePipe> mp(new MessagePipe( |
+ scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), |
+ scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); |
+ Init(mp); |
+ |
+ base::FilePath unused; |
+ base::ScopedFILE fp(CreateAndOpenTemporaryFile(&unused)); |
+ const std::string world("world"); |
+ ASSERT_EQ(fwrite(&world[0], 1, world.size(), fp.get()), world.size()); |
+ fflush(fp.get()); |
+ rewind(fp.get()); |
+ |
+ embedder::ScopedPlatformHandle h( |
+ mojo::test::PlatformHandleFromFILE(fp.Pass())); |
+ scoped_refptr<PlatformHandleDispatcher> dispatcher( |
+ new PlatformHandleDispatcher(h.Pass())); |
+ |
+ const std::string hello("hello"); |
+ DispatcherTransport transport( |
+ test::DispatcherTryStartTransport(dispatcher.get())); |
+ ASSERT_TRUE(transport.is_valid()); |
+ |
+ std::vector<DispatcherTransport> transports; |
+ transports.push_back(transport); |
+ EXPECT_EQ(MOJO_RESULT_OK, |
+ mp->WriteMessage(0, |
+ &hello[0], |
+ static_cast<uint32_t>(hello.size()), |
+ &transports, |
+ MOJO_WRITE_MESSAGE_FLAG_NONE)); |
+ transport.End(); |
+ |
+ EXPECT_TRUE(dispatcher->HasOneRef()); |
+ dispatcher = NULL; |
+ |
+ // Wait for it to become readable, which should fail. |
+ EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, |
+ WaitIfNecessary(mp, MOJO_WAIT_FLAG_READABLE)); |
+ |
+ mp->Close(0); |
+ |
+ EXPECT_EQ(0, helper()->WaitForChildShutdown()); |
+} |
+ |
} // namespace |
} // namespace system |
} // namespace mojo |